from rest_framework.permissions import BasePermission
from .models import RolePermission, MenuPermission


class HasPermission(BasePermission):
    """
    自定义权限类，检查用户是否具有特定权限
    """
    
    def __init__(self, permission_code, access_level='read'):
        self.permission_code = permission_code
        self.access_level = access_level
    
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # 超级用户拥有所有权限
        if request.user.is_superuser:
            return True
        
        # 检查用户的角色权限
        user_roles = request.user.roles.all()
        
        for role in user_roles:
            role_permissions = RolePermission.objects.filter(
                role=role,
                permission__code=self.permission_code
            )
            
            for role_perm in role_permissions:
                # 如果需要写权限，检查是否有写权限
                if self.access_level == 'write' and role_perm.access_level == 'write':
                    return True
                # 如果只需要读权限，读写权限都可以
                elif self.access_level == 'read':
                    return True
        
        # 检查用户组的角色权限
        user_groups = request.user.user_groups.all()
        for group in user_groups:
            group_users = group.customuser_set.all()
            if request.user in group_users:
                # 这里可以扩展用户组权限逻辑
                pass
        
        return False


def permission_required(permission_code, access_level='read'):
    """
    权限装饰器工厂函数
    """
    def decorator(view_func):
        def wrapper(self, request, *args, **kwargs):
            permission = HasPermission(permission_code, access_level)
            if not permission.has_permission(request, self):
                from rest_framework.response import Response
                from rest_framework import status
                return Response(
                    {'error': '权限不足'}, 
                    status=status.HTTP_403_FORBIDDEN
                )
            return view_func(self, request, *args, **kwargs)
        return wrapper
    return decorator


class RBACPermission(BasePermission):
    """
    基于RBAC的权限检查
    """
    
    # 权限映射表
    PERMISSION_MAP = {
        # 用户管理
        'CustomUserViewSet': {
            'list': 'user.view',
            'retrieve': 'user.view',
            'create': 'user.create',
            'update': 'user.edit',
            'partial_update': 'user.edit',
            'destroy': 'user.delete',
            'reset_password': 'user.reset_password',
            'toggle_status': 'user.edit',
        },
        # 用户组管理
        'UserGroupViewSet': {
            'list': 'usergroup.view',
            'retrieve': 'usergroup.view',
            'create': 'usergroup.create',
            'update': 'usergroup.edit',
            'partial_update': 'usergroup.edit',
            'destroy': 'usergroup.delete',
            'users': 'usergroup.view',
        },
        # 角色管理
        'RoleViewSet': {
            'list': 'role.view',
            'retrieve': 'role.view',
            'create': 'role.create',
            'update': 'role.edit',
            'partial_update': 'role.edit',
            'destroy': 'role.delete',
            'permissions': 'role.view',
            'assign_permissions': 'role.assign_permissions',
        },
        # 权限管理
        'PermissionViewSet': {
            'list': 'permission.view',
            'retrieve': 'permission.view',
            'create': 'permission.create',
            'update': 'permission.edit',
            'partial_update': 'permission.edit',
            'destroy': 'permission.delete',
        },
        # 菜单管理
        'MenuViewSet': {
            'list': 'menu.view',
            'retrieve': 'menu.view',
            'create': 'menu.create',
            'update': 'menu.edit',
            'partial_update': 'menu.edit',
            'destroy': 'menu.delete',
            'tree': 'menu.view',
            'permissions': 'menu.view',
        },
        # CMDB管理
        'HostViewSet': {
            'list': 'host.view',
            'retrieve': 'host.view',
            'create': 'host.create',
            'update': 'host.edit',
            'partial_update': 'host.edit',
            'destroy': 'host.delete',
            'test_connection': 'host.view',
            'execute_command': 'host.ssh',
        },
        # SQL管理
        'SQLAuditLogViewSet': {
            'list': 'sql.query',
            'retrieve': 'sql.query',
            'create': 'sql.submit',
            'approve': 'sql.audit',
            'reject': 'sql.audit',
            'execute': 'sql.execute',
        },
    }
    
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # 超级用户拥有所有权限
        if request.user.is_superuser:
            return True
        
        # 获取视图类名和动作
        view_name = view.__class__.__name__
        action = getattr(view, 'action', None)
        
        # 获取所需权限
        required_permission = self.get_required_permission(view_name, action)
        if not required_permission:
            return True  # 如果没有定义权限要求，默认允许
        
        # 检查用户权限
        return self.check_user_permission(request.user, required_permission)
    
    def get_required_permission(self, view_name, action):
        """获取视图动作所需的权限"""
        view_permissions = self.PERMISSION_MAP.get(view_name, {})
        return view_permissions.get(action)
    
    def check_user_permission(self, user, permission_code):
        """检查用户是否具有指定权限"""
        # 获取用户的所有角色
        user_roles = user.roles.all()
        
        # 检查角色权限
        for role in user_roles:
            if RolePermission.objects.filter(
                role=role,
                permission__code=permission_code
            ).exists():
                return True
        
        # 检查用户组权限（通过用户组的角色）
        user_groups = user.user_groups.all()
        for group in user_groups:
            # 这里可以扩展用户组权限逻辑
            # 例如：用户组可以有默认角色
            pass
        
        return False


def get_user_permissions(user):
    """获取用户的所有权限（基于菜单权限）"""
    if not user or not user.is_authenticated:
        return []

    if user.is_superuser:
        # 超级用户拥有所有菜单权限
        from .models import Menu
        return [f"menu.{menu.path}" for menu in Menu.objects.filter(is_active=True)]

    # 获取用户可访问的菜单，转换为权限代码
    user_menus = get_user_menus(user)
    permissions = []

    for menu in user_menus:
        # 将菜单路径转换为权限代码
        permissions.append(f"menu.{menu.path}")

        # 根据菜单生成对应的功能权限
        menu_permissions = generate_menu_permissions(menu)
        permissions.extend(menu_permissions)

    return list(set(permissions))

def generate_menu_permissions(menu):
    """根据菜单生成对应的功能权限"""
    permissions = []
    menu_path = menu.path.replace('/', '.')

    # 基础权限映射
    permission_map = {
        'user-management.users': ['user.view', 'user.create', 'user.edit', 'user.delete', 'user.reset_password'],
        'user-management.user-groups': ['usergroup.view', 'usergroup.create', 'usergroup.edit', 'usergroup.delete'],
        'user-management.roles': ['role.view', 'role.create', 'role.edit', 'role.delete', 'role.assign_permissions'],
        'host-management': ['host.view', 'host.create', 'host.edit', 'host.delete', 'ssh_connection'],
        'sql-management': ['sql_audit', 'sql.query'],
        'system-monitor': ['system_monitor']
    }

    # 查找匹配的权限
    for path_pattern, perms in permission_map.items():
        if menu_path.startswith(path_pattern):
            permissions.extend(perms)
            break

    return permissions


def get_user_menus(user):
    """获取用户可访问的菜单"""
    if not user or not user.is_authenticated:
        return []

    if user.is_superuser:
        # 超级用户可以访问所有菜单
        from .models import Menu
        return Menu.objects.filter(is_active=True).order_by('sort_order')

    accessible_menus = set()

    # 获取用户直接分配的角色可访问的菜单
    user_roles = user.roles.all()
    for role in user_roles:
        menu_permissions = MenuPermission.objects.filter(role=role)
        for mp in menu_permissions:
            accessible_menus.add(mp.menu)

    # 获取用户组继承的角色可访问的菜单
    from .models import UserGroupRole
    user_groups = user.user_groups.all()
    for group in user_groups:
        # 获取用户组分配的角色
        group_roles = UserGroupRole.objects.filter(user_group=group)
        for gr in group_roles:
            menu_permissions = MenuPermission.objects.filter(role=gr.role)
            for mp in menu_permissions:
                accessible_menus.add(mp.menu)

    # 添加父菜单（如果子菜单有权限，父菜单也应该可见）
    final_menus = set(accessible_menus)
    for menu in accessible_menus:
        parent = menu.parent
        while parent:
            final_menus.add(parent)
            parent = parent.parent

    return list(final_menus)


def get_user_menus_detail(user):
    """获取用户菜单权限的详细来源信息"""
    if not user or not user.is_authenticated:
        return {'direct_menus': [], 'group_menus': {}, 'all_menus': []}

    # 导入序列化器
    from .serializers import MenuSerializer

    if user.is_superuser:
        from .models import Menu
        all_menus = Menu.objects.filter(is_active=True)
        menu_data = MenuSerializer(all_menus, many=True).data
        return {
            'direct_menus': menu_data,
            'group_menus': {},
            'all_menus': menu_data,
            'is_superuser': True
        }

    direct_menus = set()
    group_menus = {}

    # 获取用户直接分配的角色菜单
    user_roles = user.roles.all()
    for role in user_roles:
        menu_permissions = MenuPermission.objects.filter(role=role)
        for mp in menu_permissions:
            direct_menus.add(mp.menu)

    # 获取用户组继承的角色菜单
    from .models import UserGroupRole
    user_groups = user.user_groups.all()
    for group in user_groups:
        group_menu_set = set()
        group_roles = UserGroupRole.objects.filter(user_group=group)
        for gr in group_roles:
            menu_permissions = MenuPermission.objects.filter(role=gr.role)
            for mp in menu_permissions:
                group_menu_set.add(mp.menu)
        if group_menu_set:
            group_menus[group.name] = MenuSerializer(list(group_menu_set), many=True).data

    # 合并所有菜单
    all_menus = direct_menus.copy()
    for group_menu_list in group_menus.values():
        # group_menu_list 现在是序列化后的数据，需要从中提取菜单对象
        for menu_data in group_menu_list:
            # 根据ID获取菜单对象
            from .models import Menu
            try:
                menu = Menu.objects.get(id=menu_data['id'])
                all_menus.add(menu)
            except Menu.DoesNotExist:
                pass

    # 添加父菜单
    final_menus = set(all_menus)
    for menu in all_menus:
        parent = menu.parent
        while parent:
            final_menus.add(parent)
            parent = parent.parent

    return {
        'direct_menus': MenuSerializer(list(direct_menus), many=True).data,
        'group_menus': group_menus,
        'all_menus': MenuSerializer(list(final_menus), many=True).data,
        'is_superuser': False
    }

def get_user_permissions_detail(user):
    """获取用户权限的详细来源信息（兼容旧接口）"""
    menu_detail = get_user_menus_detail(user)

    # 将菜单转换为权限代码格式
    direct_permissions = []
    for menu in menu_detail['direct_menus']:
        direct_permissions.extend(generate_menu_permissions(menu))

    group_permissions = {}
    for group_name, menus in menu_detail['group_menus'].items():
        group_perms = []
        for menu in menus:
            group_perms.extend(generate_menu_permissions(menu))
        group_permissions[group_name] = group_perms

    all_permissions = []
    for menu in menu_detail['all_menus']:
        all_permissions.extend(generate_menu_permissions(menu))

    return {
        'direct_permissions': list(set(direct_permissions)),
        'group_permissions': group_permissions,
        'all_permissions': list(set(all_permissions)),
        'is_superuser': menu_detail['is_superuser']
    }
